package org.bmi.gwt.examples.chat.client;

import org.bmi.gwt.examples.chat.shared.ChatConstants;
import org.bmi.gwt.examples.chat.shared.SenderObject;
import org.bmi.gwt.examples.chat.shared.SenderProxy;
import org.bmi.gwt.mi.client.channel.Connection;
import org.bmi.gwt.mi.client.events.ConnectionHandler;
import org.bmi.gwt.mi.shared.BroadChannel;
import org.bmi.gwt.mi.shared.Channel;
import org.bmi.gwt.mi.shared.callbacks.AttributeCallback;
import org.bmi.gwt.mi.shared.callbacks.BindCallback;
import org.bmi.gwt.mi.shared.communication.attribute.StringValue;
import org.bmi.gwt.mi.shared.exceptions.MiException;
import org.bmi.gwt.mi.shared.exceptions.NameParseException;
import org.bmi.gwt.mi.shared.exceptions.NotAllowedQueueException;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Text;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;

public abstract class MessengerWidget extends Composite
{
	private ScrollPanel responsesScroll;

	private HTML received;
	private TextArea area;

	private Button send;

	public class SenderObject_ extends SenderObject
	{
		@Override
		public void printMessage(String msg)
		{
			Text text = Document.get().createTextNode(msg);
			Element el = MessengerWidget.this.received.getElement();

			el.appendChild(DOM.createTR());
			el.appendChild(text);

			MessengerWidget.this.responsesScroll.scrollToBottom();
		}

		@Override
		public void printMessage(String msg, String fromUser)
		{
			printMessage(fromUser + ": " + msg);
		}
	}

	public MessengerWidget(final String userName) throws NameParseException, NotAllowedQueueException
	{
		Connection.createConnection(new ConnectionHandler()
		{
			@Override
			public void onException(Exception e)
			{
				initWidget(new HTML("Acess denied because: " + e.getMessage()));
			}

			@Override
			public void onConnectionBegin(Connection connection)
			{
				try
				{
					BroadChannel qSend = connection.getBroadChannel("org.bmi.gwt.mi.test.chat.*");

					final SenderProxy proxy = qSend.proxyToObject(SenderProxy.class, ChatConstants.MESSENGER_ID);

					final Grid grid = new Grid(3, 1);

					Channel ch = connection.getChannel("org.bmi.gwt.mi.test.chat." + userName, false);

					final StringValue userName1 = new StringValue(userName);

					ch.setAttribute("userName", userName1, new AttributeCallback<StringValue>()
					{
						@Override
						public void onError(MiException error)
						{
							GWT.log("an error occurred while setting attribute: ", error);
						}

						@Override
						public void onSuccess(StringValue value)
						{
							GWT.log("Set tattribuite " + value);
						}
					});

					ch.bind(new BindCallback()
					{
						@Override
						public void onError(MiException error)
						{
							GWT.log("An error occurred: " + error);
						}

						@Override
						public void onBound(Channel channel)
						{
							channel.register(ChatConstants.MESSENGER_ID, new SenderObject_());

							MessengerWidget.this.responsesScroll = new ScrollPanel();
							MessengerWidget.this.responsesScroll.setSize("300px", "300px");
							MessengerWidget.this.received = new HTML();

							MessengerWidget.this.responsesScroll.setWidget(MessengerWidget.this.received);

							MessengerWidget.this.area = new TextArea();
							MessengerWidget.this.area.setSize("300px", "50px");

							MessengerWidget.this.send = new Button("send", new ClickHandler()
							{
								@Override
								public void onClick(ClickEvent event)
								{
									proxy.printMessage(MessengerWidget.this.area.getValue(), userName);
								}
							});

							grid.setWidget(0, 0, MessengerWidget.this.responsesScroll);
							grid.setWidget(1, 0, MessengerWidget.this.area);
							grid.setWidget(2, 0, MessengerWidget.this.send);

							initWidget(grid);

							onReady(MessengerWidget.this);
						}
					});
				}
				catch (NameParseException e)
				{
					GWT.log("", e);
				}
			}
		});
	}

	protected abstract void onReady(MessengerWidget messenger);
}
